﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using Citi.Helpers;
using Citi.ReportManager.Domain;

namespace Citi.ReportManager.Util
{
    public abstract class CopyFile
    {
        public abstract string StepDescription { set; }

        private string FilesPath
        {
            get
            {
                var filesPath = ConfigurationManager.AppSettings["FilesPath"];

                if (filesPath.ToUpper().Contains(Environment.MachineName.ToUpper()))
                {
                    filesPath = filesPath.ToLower()
                        .Replace(string.Format(@"\\{0}.lac.nsroot.net\c$\", Environment.MachineName.ToLower()), @"C:\")
                        .Replace(string.Format(@"\\{0}\C$\", Environment.MachineName.ToLower()), @"C:\");
                }

                return filesPath;
            }
        }

        private List<ReportFolder> ReportFolders { get; set; }
        private List<SupportedExtension> SupportedExtensions { get; set; }

        public void StartCopy(List<ReportFolder> reportFolders)
        {
            ReportFolders = reportFolders;
            StepDescription = "Loading supported extensions";
            SupportedExtensions = new SupportedExtension().SelectAll<SupportedExtension>();

            foreach (var reportFolder in ReportFolders)
            {
                StepDescription = string.Format("Category: '{0}'", reportFolder.Category.Name);
                var directoryToSave = Path.Combine(FilesPath, reportFolder.CategoryId.ToString());

                StepDescription = string.Format("Reading Directory: '{0}'", directoryToSave);
                if (!Directory.Exists(directoryToSave)) Directory.CreateDirectory(directoryToSave);

                MoveFiles(reportFolder.FolderPath, directoryToSave, reportFolder);

                if (reportFolder.IncludeDirectories)
                    CopyDirectories(reportFolder.FolderPath, directoryToSave, reportFolder);
            }
        }

        private void CopyDirectories(string directoryPath, string pathToSave, ReportFolder reportFolder)
        {
            var directories = Directory.GetDirectories(directoryPath).Where(x => !ReportFolders.Select(y => y.FolderPath).Contains(x));

            foreach (var directory in directories)
            {
                var directoryToSave = Path.Combine(pathToSave, Path.GetFileName(directory));

                StepDescription = string.Format("Reading Directory: '{0}'", directoryToSave);
                if (!Directory.Exists(directoryToSave)) Directory.CreateDirectory(directoryToSave);

                MoveFiles(directory, directoryToSave, reportFolder);

                if (Directory.GetDirectories(directory).Any())
                    CopyDirectories(directory, directoryToSave, reportFolder);
            }
        }

        private void MoveFiles(string directoryPath, string pathToSave, ReportFolder reportFolder)
        {
            var files = Directory.GetFiles(directoryPath)
                .Where(x => SupportedExtensions.Any(y => y.Extension == Path.GetExtension(x).Substring(1))).ToList();

            files.ForEach(file =>
            {
                var finalPathToSave = Path.Combine(pathToSave, reportFolder.SeparateInFolder ? File.GetLastWriteTime(file).ToString("yyyy.MM") : string.Empty);

                if (!Directory.Exists(finalPathToSave)) Directory.CreateDirectory(finalPathToSave);

                var newFile = ConvertToXlsb(reportFolder, file);

                if (Path.GetExtension(newFile).ToLower() != ".zip")
                {
                    var zipFile = Path.Combine(finalPathToSave, string.Concat(Path.GetFileName(newFile), ".zip"));

                    if (!File.Exists(zipFile))
                    {
                        FileHelper.CompressFile(newFile, zipFile);
                        SaveReport(reportFolder, file, zipFile);
                    }
                }
                else
                {
                    if (!File.Exists(newFile))
                        SaveReport(reportFolder, file, newFile);
                }

                if (reportFolder.MoveFilePermanently && File.GetLastWriteTime(file) < DateTime.Today.AddDays(-reportFolder.DaysToBackup))
                {
                    File.Delete(newFile);
                    File.Delete(file);
                }

                //if (reportFolder.MoveFilePermanently)
                //{
                //    if (File.Exists(fileToSave)) File.Delete(fileToSave);
                //    File.Move(file, fileToSave);
                //}
                //else
                //    File.Copy(file, fileToSave, true);
            });
        }

        private string ConvertToXlsb(ReportFolder reportFolder, string file)
        {
            if (reportFolder.CanConvertToXlsb && (Path.GetExtension(file).ToLower() == ".xlsx" || Path.GetExtension(file).ToLower() == ".xls"))
            {
                try
                {
                    var convertedFile = Path.Combine(@"c:\temp", string.Concat(Path.GetFileNameWithoutExtension(file), ".xlsb"));

                    if (File.Exists(convertedFile)) File.Delete(convertedFile);

                    ExcelHelper.ConvertXlsToXlsb(file, convertedFile);

                    return convertedFile;
                }
                catch
                {
                    return file;
                }
            }

            return file;
        }

        private void SaveReport(ReportFolder reportFolder, string file, string fileToSave)
        {
            var report = new Report
            {
                CategoryId = reportFolder.CategoryId,
                FileDate = File.GetLastWriteTime(file),
                InsertDate = DateTime.Now,
                ReportName = fileToSave.Replace(string.Format(@"{0}\{1}\", FilesPath, reportFolder.CategoryId), string.Empty),
                ExtensionId = SupportedExtensions.First(x => x.Extension == Path.GetExtension(file).Substring(1)).Id
            };
            report.Save(report);
        }
    }
}
